package com.zkyt.lib_msdk_ext.component

import com.geoai.mavlink.geoainet.rtk.enums.RtkComponentType
import com.geoai.mavlink.geoainet.rtk.info.RtkEntryInfo
import com.geoai.mavlink.geoainet.rtk.interfaces.IBaseRtkManager
import com.zkyt.lib_msdk_ext.common.CompletionCbRxHandler
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.subjects.BehaviorSubject
import java.util.Optional

/**
 * Created by chenyu on 2024/1/17
 * Description:
 */
object RtkManagerExt : AbsSDKExt<IBaseRtkManager>(), IRemovableComp {
    private val isConnectSubject = BehaviorSubject.createDefault(false)
    private var rtkManager: IBaseRtkManager? = null

    private var originRtkStateSubject =
        BehaviorSubject.createDefault(Optional.empty<RtkEntryInfo>())

    override fun init(originManager: IBaseRtkManager) {
        rtkManager = originManager

        rtkManager?.setRtkStateListener {
            originRtkStateSubject.onNext(Optional.of(it))
        }
        isConnectSubject.onNext(true)
    }

    override fun isConnected(): Boolean {
        return isConnectSubject.value!!
    }

    override fun getConnectedObservable(): Observable<Boolean> {
        return isConnectSubject.hide()
    }

    override fun destroy() {
        super.destroy()
        isConnectSubject.onNext(false)
        rtkManager?.setRtkStateListener(null)
        originRtkStateSubject.onNext(Optional.ofNullable(null))

        rtkManager = null
    }

    override fun getOriginManager(): IBaseRtkManager? {
        return rtkManager
    }

    fun getRtkStateInfoObservable(): Observable<Optional<RtkEntryInfo>> {
        return originRtkStateSubject.hide()
    }

    fun setRtkEnableRx(enable: Boolean): Completable {
        return Completable.create { emitter ->
            rtkManager?.setRtkEnable(enable, CompletionCbRxHandler(emitter))
        }
    }

    fun getRtkEnableRx(): Single<Boolean> {
        return Single.create { emitter ->
            val rtkEnable = rtkManager?.rtkEnable
            emitter.onSuccess(rtkEnable == true)
        }
    }

    fun getRtkEnableObservable(): Observable<Optional<Boolean>> {
        val curMethod = object : Any() {}.javaClass.enclosingMethod
        return autoGetProcessor.getAutoGetSubject(curMethod, this::getRtkEnableRx, 2000)
    }

    fun connectRx(): Completable {
        return Completable.create { emitter ->
            rtkManager?.connectRTK(CompletionCbRxHandler(emitter))
        }
    }

    fun setRtkComponentType(type: RtkComponentType): Boolean {
        return if (rtkManager == null) false else {
            rtkManager?.rtkComponentType = type
            true
        }
    }

    fun getRtkComponentType(): Optional<RtkComponentType> {
        return if (rtkManager == null) Optional.empty() else {
            Optional.of(rtkManager!!.rtkComponentType)
        }
    }

}